﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration;
using Chisholm.Windows.Live.Library;

namespace Chisholm.Windows.Live.SSOServer
{
    /// <summary>
    /// This class provides functionality for starting and stopping the WCF service which drives
    /// the SSO Server
    /// </summary>
    public static class ServiceManager
    {
        private static SSOServerEngine _hostedservice;
        /// <summary>
        /// This is the SSO Engine Service to expose
        /// </summary>
        internal static SSOServerEngine HostedService
        {
            get
            {
                if (_hostedservice == null)
                    _hostedservice = new SSOServerEngine();

                return _hostedservice;
            }
            set { _hostedservice = value; }
        }

        /// <summary>
        /// The host of the service
        /// </summary>
        private static ServiceHost host;

        /// <summary>
        /// This will start the SSO Server Engine service on the specified endpoint
        /// </summary>
        /// <returns>The errors (if any) that occurred during the starting of the service</returns>
        internal static List<string> StartService()
        {
            // Create our errors list for returning
            List<string> errors = new List<string>();

            // Grab our settings from the application settings
            string servername = ConfigurationManager.AppSettings["Server"];
            int port = 11000;
            int.TryParse(ConfigurationManager.AppSettings["Port"], out port);

            // Prepare our end point for hosting
            List<Uri> endpoints = new List<Uri>();
            endpoints.Add(new Uri("net.tcp://" + servername + ":" + port.ToString() + "/"));

            // Initialise our host service with those endpoints
            host = new ServiceHost(HostedService, endpoints.ToArray());

            // Prepare our binding
            NetTcpBinding tcpbinding = new NetTcpBinding();
            tcpbinding.MaxReceivedMessageSize = Int32.MaxValue;
            tcpbinding.ReaderQuotas.MaxDepth = Int32.MaxValue;
            tcpbinding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
            tcpbinding.ReceiveTimeout = new TimeSpan(0, 60, 0);
            tcpbinding.SendTimeout = new TimeSpan(0, 60, 0);
            tcpbinding.CloseTimeout = new TimeSpan(0, 60, 0);

            // Add the new end point based on the binding
            host.AddServiceEndpoint(typeof(ISSOServerEngine), tcpbinding, "/SSOServer");

            // Then try and open the host for communication
            try
            {
                host.Open();
            }
            catch (AddressAccessDeniedException addressdenied)
            {
                errors.Add("An error occurred while trying to start the service. The error was caused by the fact that the HTTP namespace is reserved. Please see http://msdn2.microsoft.com/en-us/library/ms733768.aspx for more details.");
                errors.Add(addressdenied.Message);
            }
            catch (Exception e1)
            {
                errors.Add("An unknown error occurred when trying to start the service. The error was: " + e1.ToString());
            }

            // Return our errors list
            return errors;
        }

        /// <summary>
        /// This will stop the service and cleanly dismount it
        /// </summary>
        internal static void StopService()
        {
            if (host != null && host.State == CommunicationState.Opened || host.State == CommunicationState.Opening)
                host.Close();
        }
    }
}
